//---------------------------------------------------------------------
// 
//  Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;

namespace Glpt.Common
{
    /// <summary>
    /// 自定义的DataGridView组件
    /// </summary>
    public class GJDataGridView : DataGridView
    {
        /// <summary>
        /// 树状时的层级号列名
        /// </summary>
        public const string ATTR_TREE_LEVEL_NO = "ATTR_TREE_LEVEL_NO";
        /// <summary>
        /// 树状时的级别列名
        /// </summary>
        public const string ATTR_TREE_LEVEL = "ATTR_TREE_LEVEL";
        /// <summary>
        /// 树状时的图标名称
        /// </summary>
        public const string ATTR_TREE_ICON = "ATTR_TREE_ICON";

        private TreeGridNode _root;
        private TreeGridColumn _expandableColumn;
        internal ImageList _imageList;
        private bool _inExpandCollapse = false;
        internal bool _inExpandCollapseMouseCapture = false;
        private Control hideScrollBarControl;
        /// <summary>
        /// 奇数行的背景颜色
        /// </summary>
        public Color AlternatingRowsBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
        /// <summary>
        /// 事件启用是否
        /// </summary>
        public bool EnableEvent = true;
        private bool _showLines = true;
        private bool _virtualNodes = false;
        private object _dataSource = null;

        /// <summary>
        /// 多表头信息
        /// </summary>
        public List<ColumnLayer> layers = null;

        /// <summary>
        /// 初始化类的新实例
        /// </summary>
        public GJDataGridView()
            : base()
        {
            base.AutoGenerateColumns = false;
            base.AllowUserToAddRows = false;
            base.AllowUserToDeleteRows = false;
            base.AllowUserToOrderColumns = true;
            base.AllowUserToResizeRows = false;
            base.AlternatingRowsDefaultCellStyle.BackColor = AlternatingRowsBackColor;
            base.BackgroundColor = System.Drawing.SystemColors.Window;
            DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
            dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
            dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
            dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
            dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
            dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
            dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
            base.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
            base.ColumnHeadersHeight = 21;
            base.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            base.RowHeadersWidth = 21;
            base.RowTemplate.Height = 23;
            base.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            base.Rows.CollectionChanged += delegate (object sender, System.ComponentModel.CollectionChangeEventArgs e) { };
        }

        /// <summary>
        /// 获取或设置控件的垂直滚动条是否可见
        /// </summary>
        public bool VerticalScrollBarVisible
        {
            get
            {
                return VerticalScrollBar.Visible;
            }
            set
            {
                VerticalScrollBar.Visible = value;
            }
        }

        /// <summary>
        /// 获取或设置控件的水平滚动条是否可见
        /// </summary>
        public bool HorizontalScrollBarVisible
        {
            get
            {
                return this.HorizontalScrollBar.Visible;
            }
            set
            {
                HorizontalScrollBar.Visible = value;
            }
        }

        /// <summary>
        /// 获取或设置控件的垂直滚动条是否可用
        /// </summary>
        public bool VerticalScrollBarEnabled
        {
            get
            {
                return VerticalScrollBar.Enabled;
            }
            set
            {
                VerticalScrollBar.Enabled = value;
            }
        }

        /// <summary>
        /// 添加行号显示
        /// </summary>
        public void AddRowPostPaint()
        {
            base.RowPostPaint += new DataGridViewRowPostPaintEventHandler(DataGridViewAdv_RowPostPaint);
        }

        private void DataGridViewAdv_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            if (this.RowHeadersVisible)
            {
                Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, this.RowHeadersWidth - 4, e.RowBounds.Height);
                TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), this.RowHeadersDefaultCellStyle.Font, rectangle, this.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
            }
        }

        #region Keyboard F2 to begin edit support
        /// <summary>
        /// 引发 System.Windows.Forms.Control.KeyDown 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.KeyEventArgs。</param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            // Cause edit mode to begin since edit mode is disabled to support 
            // expanding/collapsing 
            base.OnKeyDown(e);
            if (this._root == null) return;
            if (!e.Handled)
            {
                if (e.KeyCode == Keys.F2 && this.CurrentCellAddress.X > -1 && this.CurrentCellAddress.Y > -1)
                {
                    if (!this.CurrentCell.Displayed)
                    {
                        this.FirstDisplayedScrollingRowIndex = this.CurrentCellAddress.Y;
                    }
                    else
                    {
                        // TODO:calculate if the cell is partially offscreen and if so scroll into view
                    }
                    this.SelectionMode = DataGridViewSelectionMode.CellSelect;
                    this.BeginEdit(true);
                }
                else if (e.KeyCode == Keys.Enter && !this.IsCurrentCellInEditMode)
                {
                    this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                    this.CurrentCell.OwningRow.Selected = true;
                }
            }
        }
        #endregion

        /// <summary>
        ///  获取或设置数据源
        /// </summary>
        public new object DataSource
        {
            get
            {
                if (_dataSource != null)
                    return _dataSource;
                else
                    return base.DataSource;
            }
            set
            {
                this.RowTemplate = new DataGridViewRow();
                if (value is DataTable || value is DataView)
                {
                    DataTable dt = null;
                    DataRow[] drs = null;
                    if (value is DataView)
                    {
                        DataView dv = (DataView)value;
                        dt = dv.Table;
                        drs = dt.Select(dv.RowFilter, dv.Sort);
                    }
                    else
                    {
                        dt = (DataTable)value;
                        drs = dt.Select("");
                    }
                    if (dt.Columns.Contains(ATTR_TREE_ICON))
                    {
                        this.ImageList = new ImageList();
                    }
                    else
                        this.ImageList = null;
                    if (dt.Columns.Contains(ATTR_TREE_LEVEL_NO) && dt.Columns.Contains(ATTR_TREE_LEVEL))
                    {
                        _dataSource = value;
                        base.DataSource = null;
                        this.RowTemplate = new TreeGridNode() as DataGridViewRow;

                        if (this._root != null)
                        {
                            this._root.ClearNodes();
                            this._root = null;
                        }
                        this._root = new TreeGridNode(this);
                        this._root.IsRoot = true;

                        TreeGridNode[] tgds = new TreeGridNode[drs.Length];
                        for (int i = 0; i < tgds.Length; i++)
                        {
                            int level_no = 0;
                            if (!int.TryParse(drs[i][ATTR_TREE_LEVEL_NO].ToString(), out level_no))
                                throw new Exception(ATTR_TREE_LEVEL_NO + "字段必须为数值类型！");
                            for (int k = 0; k < i; k++)
                            {
                                if (tgds[k].TreeLevelNo == level_no - 1 && drs[i][ATTR_TREE_LEVEL].ToString().StartsWith(tgds[k].TreeLevel))
                                {
                                    tgds[i] = tgds[k].Nodes.Add(drs[i]);
                                    break;
                                }
                            }
                            if (tgds[i] == null)
                            {
                                tgds[i] = this.Nodes.Add(drs[i]);
                            }
                            if (dt.Columns.Contains(ATTR_TREE_ICON))
                            {
                                string filename = drs[i][ATTR_TREE_ICON].ToString();
                                UpdateNodeImage(tgds[i], filename);
                            }
                        }
                    }
                    else
                    {
                        if (this._root != null)
                        {
                            this._root.ClearNodes();
                            this._root = null;
                        }
                        _dataSource = null;
                        base.DataSource = value;
                    }
                }
                else
                {
                    if (this._root != null)
                    {
                        this._root.ClearNodes();
                        this._root = null;
                    }
                    _dataSource = null;
                    base.DataSource = value;
                }
            }
        }

        /// <summary>
        /// 更新图标
        /// </summary>
        /// <param name="tgn">节点</param>
        /// <param name="filename">文件名</param>
        public void UpdateNodeImage(TreeGridNode tgn, string filename)
        {
            if (filename.Length > 0)
            {
                if (!this.ImageList.Images.ContainsKey(filename))
                {
                    Bitmap img = Funcs.GetImage(filename);
                    if (img != null) this.ImageList.Images.Add(filename, Funcs.GetImage(filename));
                }
                int idx = this.ImageList.Images.IndexOfKey(filename);
                if (idx >= 0) tgn.ImageIndex = idx;
            }
            else
                tgn.ImageIndex = -1;
        }

        /// <summary>
        /// 获取或设置一个值，该值指示您是否为控件提供了自己的数据管理操作
        /// </summary>
        public new bool VirtualMode
        {
            get
            {
                if (this._root == null)
                    return base.VirtualMode;
                else
                    return false;
            }
            set
            {
                if (this._root == null)
                    base.VirtualMode = value;
            }
        }

        /// <summary>
        /// 获取指定行的节点
        /// </summary>
        /// <param name="row">数据行</param>
        /// <returns>节点</returns>
        public TreeGridNode GetNodeForRow(DataGridViewRow row)
        {
            return row as TreeGridNode;
        }

        /// <summary>
        /// 获取指定索引号的节点
        /// </summary>
        /// <param name="index">索引号</param>
        /// <returns>节点</returns>
        public TreeGridNode GetNodeForRow(int index)
        {
            return GetNodeForRow(base.Rows[index]);
        }

        /// <summary>
        /// OnCellPainting
        /// </summary>
        /// <param name="e"></param>
        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex > -1 || e.ColumnIndex < 0)
            {
                base.OnCellPainting(e);
                return;
            }

            //单层表头则让系统自己绘制
            if (layers == null)
            {
                base.OnCellPainting(e);
                return;
            }
            List<ColumnLayer> curLayer = layers.FindAll(L => L.ColumnIndex == e.ColumnIndex);
            //if (curLayer.Count <= 1)
            //{
            //    base.OnCellPainting(e);
            //    return;
            //}

            this.AllowUserToOrderColumns = false; //多表头不允许调整列顺序

            int depth = layers.Max(L => L.Level) + 1;
            int unitH = base.RowTemplate.Height;
            int columnH = unitH * depth;
            if (this.ColumnHeadersHeight < columnH) this.ColumnHeadersHeight = columnH;
            if (depth > 1) this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;

            Color c1 = Color.White;
            Color c2 = e.CellStyle.BackColor;
            Pen penGrid = new Pen(this.GridColor);
            Graphics g = e.Graphics;
            using (LinearGradientBrush br = new LinearGradientBrush(e.CellBounds, c1, c2, 90f))
            {
                g.FillRectangle(br, e.CellBounds); //绘制背景
            }
            foreach (ColumnLayer layer in curLayer)
            {
                Rectangle rect = e.CellBounds;
                rect.Y += layer.Level * unitH;
                rect.Height = layer.RowSpan * unitH;
                rect.X -= 1;
                int index = e.ColumnIndex;
                if (layer.LeftSpan > 0) // 向左调整绘制区域
                {
                    for (int count = 0, idx = index - 1; count < layer.LeftSpan; count++, idx--)
                    {
                        rect.X -= this.Columns[idx].Width;
                        rect.Width += this.Columns[idx].Width;
                    }
                }
                if (layer.RightSpan > 0) // 向右调整绘制区域
                {
                    for (int count = 0, idx = index + 1; count < layer.RightSpan; count++, idx++)
                    {
                        rect.Width += this.Columns[idx].Width;
                    }
                }
                if (rect.X < 1)
                    rect.X = 1;

                // 绘制边框 
                g.DrawRectangle(penGrid, rect);
                // 绘制文本
                Font f = e.CellStyle.Font;
                Color foreColor = e.CellStyle.ForeColor;
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                TextRenderer.DrawText(e.Graphics, layer.Title, f, rect, foreColor);
            }
            // 绘制底部线 
            g.DrawLine(penGrid, e.CellBounds.X, e.CellBounds.Height - 1, e.CellBounds.Right, e.CellBounds.Height - 1);
            penGrid.Dispose();

            // 绘制排序标示
            if (this.SortedColumn != null && this.SortedColumn.Index == e.ColumnIndex)
            {
                ColumnLayer bottomLayer = curLayer[curLayer.Count - 1];
                int x = e.CellBounds.Right - 14;
                int y = e.CellBounds.Y + bottomLayer.Level * unitH;
                int h = bottomLayer.RowSpan * unitH;
                y += h / 2;
                if (this.SortOrder == System.Windows.Forms.SortOrder.Ascending)
                    g.FillPolygon(Brushes.Gray, new Point[] {
                        new Point(x-1, y + 2), new Point(x + 5, y - 4), new Point(x + 11, y + 2) });
                else
                    g.FillPolygon(Brushes.Gray, new Point[] {
                        new Point(x, y - 2), new Point(x + 5, y + 3), new Point(x + 10, y - 2) });
            }

            e.Handled = true;
        }

        /// <summary>
        /// OnScroll
        /// </summary>
        /// <param name="e"></param>
        protected override void OnScroll(ScrollEventArgs e)
        {
            if (layers != null)
                this.Invalidate();
            base.OnScroll(e);
        }

        /// <summary>
        /// OnColumnWidthChanged
        /// </summary>
        /// <param name="e"></param>
        protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e)
        {
            if (layers != null)
                this.Invalidate();
            base.OnColumnWidthChanged(e);
        }

        #region Public properties

        /// <summary>
        /// 全部节点的集合
        /// </summary>
        public TreeGridNodeCollection Nodes
        {
            get
            {
                return this._root.Nodes;
            }
        }

        /// <summary>
        /// Causes nodes to always show as expandable. Use the NodeExpanding event to add nodes.
        /// </summary>
        public bool VirtualNodes
        {
            get { return _virtualNodes; }
            set { _virtualNodes = value; }
        }

        /// <summary>
        /// 当前节点
        /// </summary>
        public TreeGridNode CurrentNode
        {
            get
            {
                return base.CurrentRow as TreeGridNode;
            }
        }

        /// <summary>
        /// 是否显示树线
        /// </summary>
        public bool ShowLines
        {
            get
            {
                return this._showLines;
            }
            set
            {
                if (value != this._showLines)
                {
                    this._showLines = value;
                    this.Invalidate();
                }
            }
        }

        /// <summary>
        /// 树节点的图片
        /// </summary>
        public ImageList ImageList
        {
            get { return this._imageList; }
            set
            {
                this._imageList = value;
            }
        }

        /// <summary>
        /// 获取或设置显示的行数
        /// </summary>
        public new int RowCount
        {
            get
            {
                if (this._root == null)
                    return base.RowCount;
                else
                    return this.Nodes.Count;
            }
            set
            {
                if (this._root == null)
                    base.RowCount = value;
                else
                    for (int i = 0; i < value; i++)
                        this.Nodes.Add(new TreeGridNode());

            }
        }
        #endregion

        #region Site nodes and collapse/expand support

        /// <summary>
        /// 展开所有树节点
        /// </summary>
        public void ExpandAll()
        {
            if (this._root == null) return;
            for (int i = 0; i < this.Nodes.Count; i++)
            {
                ExpandAll(this.Nodes[i]);
            }
        }

        /// <summary>
        /// 展开所有树节点
        /// </summary>
        /// <param name="node">节点</param>
        public void ExpandAll(TreeGridNode node)
        {
            ExpandNode(node);
            for (int i = 0; i < node.Nodes.Count; i++)
            {
                ExpandAll(node.Nodes[i]);
            }
        }

        /// <summary>
        /// 折叠所有树节点
        /// </summary>
        public void CollapseAll()
        {
            for (int i = 0; i < this.Nodes.Count; i++)
            {
                CollapseNode(this.Nodes[i]);
            }
        }

        /// <summary>
        /// 展开所有树节点
        /// </summary>
        /// <param name="node">节点</param>
        public void CollapseAll(TreeGridNode node)
        {
            for (int i = 0; i < node.Nodes.Count; i++)
            {
                CollapseNode(node.Nodes[i]);
            }
        }

        /// <summary>
        /// 引发 System.Windows.Forms.DataGridView.RowsAdded 事件。
        /// </summary>
        /// <param name="e">一个 System.Windows.Forms.DataGridViewRowsAddedEventArgs，包含有关已添加的行的信息。</param>
        protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
        {
            base.OnRowsAdded(e);
            if (this._root == null) return;
            // Notify the row when it is added to the base grid 
            int count = e.RowCount - 1;
            TreeGridNode row;
            while (count >= 0)
            {
                row = base.Rows[e.RowIndex + count] as TreeGridNode;
                if (row != null)
                {
                    row.Sited();
                }
                count--;
            }
        }
        /// <summary>
        /// 删除全部树节点
        /// </summary>
        internal protected void UnSiteAll()
        {
            if (this._root == null) return;
            this.EnableEvent = false;
            this.UnSiteNode(this._root);
            this.EnableEvent = true;
        }
        /// <summary>
        /// 删除指定树节点
        /// </summary>
        /// <param name="node">节点</param>
        public void UnSiteNode(TreeGridNode node)
        {
            if (this._root == null) return;
            if (node.IsSited || node.IsRoot)
            {
                // remove child rows first
                foreach (TreeGridNode childNode in node.Nodes)
                {
                    this.UnSiteNode(childNode);
                }

                // now remove this row except for the root
                if (!node.IsRoot)
                {
                    if (node.RowIndex >= 0)
                        base.Rows.Remove(node);
                    // Row isn't sited in the grid anymore after remove. Note that we cannot
                    // Use the RowRemoved event since we cannot map from the row index to
                    // the index of the expandable row/node.
                    node.UnSited();
                }
            }
        }
        /// <summary>
        /// 折叠树节点
        /// </summary>
        /// <param name="node">节点</param>
        /// <returns>是否折叠成功</returns>
        internal protected virtual bool CollapseNode(TreeGridNode node)
        {
            if (node.IsExpanded)
            {
                CollapsingEventArgs exp = new CollapsingEventArgs(node);
                this.OnNodeCollapsing(exp);

                if (!exp.Cancel)
                {
                    this.LockVerticalScrollBarUpdate(true);
                    this.SuspendLayout();
                    _inExpandCollapse = true;
                    node.IsExpanded = false;
                    foreach (TreeGridNode childNode in node.Nodes)
                    {
                        //Debug.Assert(childNode.RowIndex != -1, "Row is NOT in the grid.");
                        this.UnSiteNode(childNode);
                    }
                    CollapsedEventArgs exped = new CollapsedEventArgs(node);
                    this.OnNodeCollapsed(exped);
                    //TODO: Convert this to a specific NodeCell property
                    _inExpandCollapse = false;
                    this.LockVerticalScrollBarUpdate(false);
                    this.ResumeLayout(true);
                    this.InvalidateCell(node.Cells[0]);

                }

                return !exp.Cancel;
            }
            else
            {
                // row isn't expanded, so we didn't do anything.				
                return false;
            }
        }

        /// <summary>
        /// 添加树节点
        /// </summary>
        /// <param name="node">节点</param>
        internal protected virtual void SiteNode(TreeGridNode node)
        {
            if (this._root == null) return;
            //TODO: Raise exception if parent node is not the root or is not sited.
            int rowIndex = -1;
            TreeGridNode currentRow;
            node._grid = this;

            if (node.Parent != null && node.Parent.IsRoot == false)
            {
                // row is a child
                //Debug.Assert(node.Parent != null && node.Parent.IsExpanded == true);

                if (node.Index > 0)
                {
                    currentRow = node.Parent.Nodes[node.Index - 1];
                }
                else
                {
                    currentRow = node.Parent;
                }
            }
            else
            {
                // row is being added to the root
                if (node.Index > 0)
                {
                    currentRow = node.Parent.Nodes[node.Index - 1];
                }
                else
                {
                    currentRow = null;
                }

            }

            if (currentRow != null)
            {
                while (currentRow.Level >= node.Level)
                {
                    if (currentRow.RowIndex < base.Rows.Count - 1)
                    {
                        currentRow = base.Rows[currentRow.RowIndex + 1] as TreeGridNode;
                        //Debug.Assert(currentRow != null);
                    }
                    else
                        // no more rows, site this node at the end.
                        break;

                }
                if (currentRow == node.Parent)
                    rowIndex = currentRow.RowIndex + 1;
                else if (currentRow.Level < node.Level)
                    rowIndex = currentRow.RowIndex;
                else
                    rowIndex = currentRow.RowIndex + 1;
            }
            else
                rowIndex = 0;


            //Debug.Assert(rowIndex != -1);
            this.SiteNode(node, rowIndex);

            //Debug.Assert(node.IsSited);
            if (node.IsExpanded)
            {
                // add all child rows to display
                foreach (TreeGridNode childNode in node.Nodes)
                {
                    //TODO: could use the more efficient SiteRow with index.
                    this.SiteNode(childNode);
                }
            }
        }

        /// <summary>
        /// 插入指定树节点
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="index">索引号</param>
        internal protected virtual void SiteNode(TreeGridNode node, int index)
        {
            if (this._root == null) return;
            if (index < base.Rows.Count)
            {
                base.Rows.Insert(index, node);
            }
            else
            {
                // for the last item.
                base.Rows.Add(node);
            }
        }
        /// <summary>
        /// 展开树节点
        /// </summary>
        /// <param name="node">节点</param>
        /// <returns>是否操作成功</returns>
        internal protected virtual bool ExpandNode(TreeGridNode node)
        {
            if (!node.IsExpanded || this._virtualNodes)
            {
                ExpandingEventArgs exp = new ExpandingEventArgs(node);
                this.OnNodeExpanding(exp);

                if (!exp.Cancel)
                {
                    this.LockVerticalScrollBarUpdate(true);

                    this.SuspendLayout();
                    _inExpandCollapse = true;
                    node.IsExpanded = true;
                    //TODO Convert this to a InsertRange
                    foreach (TreeGridNode childNode in node.Nodes)
                    {
                        childNode.Visible = false;
                        //Debug.Assert(childNode.RowIndex == -1, "Row is already in the grid.");
                        this.SiteNode(childNode);
                        //this.BaseRows.Insert(rowIndex + 1, childRow);
                    }
                    foreach (TreeGridNode childNode in node.Nodes)
                    {
                        childNode.Visible = true;
                    }

                    ExpandedEventArgs exped = new ExpandedEventArgs(node);
                    this.OnNodeExpanded(exped);
                    //TODO: Convert this to a specific NodeCell property
                    _inExpandCollapse = false;
                    this.LockVerticalScrollBarUpdate(false);
                    this.ResumeLayout(true);
                    this.InvalidateCell(node.Cells[0]);
                }

                return !exp.Cancel;
            }
            else
            {
                // row is already expanded, so we didn't do anything.
                return false;
            }
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseUp 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.MouseEventArgs。</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            // used to keep extra mouse moves from selecting more rows when collapsing
            base.OnMouseUp(e);
            this._inExpandCollapseMouseCapture = false;
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseMove 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.MouseEventArgs。</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            // while we are expanding and collapsing a node mouse moves are
            // supressed to keep selections from being messed up.
            if (!this._inExpandCollapseMouseCapture)
                base.OnMouseMove(e);

        }
        #endregion

        #region Collapse/Expand events
        /// <summary>
        /// 节点正在展开事件
        /// </summary>
        public event ExpandingEventHandler NodeExpanding;
        /// <summary>
        /// 节点展开后事件
        /// </summary>
        public event ExpandedEventHandler NodeExpanded;
        /// <summary>
        /// 节点正在折叠事件
        /// </summary>
        public event CollapsingEventHandler NodeCollapsing;
        /// <summary>
        /// 节点折叠后事件
        /// </summary>
        public event CollapsedEventHandler NodeCollapsed;
        /// <summary>
        /// 引发节点正在展开事件。
        /// </summary>
        /// <param name="e">包含事件数据的 ExpandingEventArgs。</param>
        protected virtual void OnNodeExpanding(ExpandingEventArgs e)
        {
            if (this.NodeExpanding != null)
            {
                NodeExpanding(this, e);
            }
        }
        /// <summary>
        /// 引发节点展开后事件。
        /// </summary>
        /// <param name="e">包含事件数据的 ExpandedEventArgs。</param>
        protected virtual void OnNodeExpanded(ExpandedEventArgs e)
        {
            if (this.NodeExpanded != null)
            {
                NodeExpanded(this, e);
            }
        }
        /// <summary>
        /// 引发节点正在折叠事件。
        /// </summary>
        /// <param name="e">包含事件数据的 CollapsingEventArgs。</param>
        protected virtual void OnNodeCollapsing(CollapsingEventArgs e)
        {
            if (this.NodeCollapsing != null)
            {
                NodeCollapsing(this, e);
            }

        }
        /// <summary>
        /// 引发节点折叠后事件。
        /// </summary>
        /// <param name="e">包含事件数据的 CollapsedEventArgs。</param>
        protected virtual void OnNodeCollapsed(CollapsedEventArgs e)
        {
            if (this.NodeCollapsed != null)
            {
                NodeCollapsed(this, e);
            }
        }
        #endregion

        #region Helper methods
        /// <summary>
        /// 释放非托管资源
        /// </summary>
        /// <param name="disposing">为 true 则释放托管资源和非托管资源；为 false 则仅释放非托管资源。</param>
        protected override void Dispose(bool disposing)
        {
            if (this._root != null)
                this.UnSiteAll();
            base.Dispose(disposing);
            _dataSource = null;
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.HandleCreated 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            if (this._root == null) return;
            // this control is used to temporarly hide the vertical scroll bar
            hideScrollBarControl = new Control();
            hideScrollBarControl.Visible = false;
            hideScrollBarControl.Enabled = false;
            hideScrollBarControl.TabStop = false;
            // control is disposed automatically when the grid is disposed
            this.Controls.Add(hideScrollBarControl);
        }

        /// <summary>
        /// 引发 System.Windows.Forms.DataGridView.RowEnter 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.DataGridViewCellEventArgs。</param>
        protected override void OnRowEnter(DataGridViewCellEventArgs e)
        {
            // ensure full row select
            base.OnRowEnter(e);
            if (this._root == null) return;
            if (this.SelectionMode == DataGridViewSelectionMode.CellSelect ||
                (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect &&
                base.Rows[e.RowIndex].Selected == false))
            {
                this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                base.Rows[e.RowIndex].Selected = true;
            }
        }
        /// <summary>
        /// Temporarly hide/show the vertical scroll bar by changing its parent
        /// </summary>
        /// <param name="lockUpdate">lockUpdate</param>
        private void LockVerticalScrollBarUpdate(bool lockUpdate/*, bool delayed*/)
        {
            // Temporarly hide/show the vertical scroll bar by changing its parent
            if (!this._inExpandCollapse)
            {
                EnableEvent = !lockUpdate;
                if (lockUpdate)
                {
                    this.VerticalScrollBar.Parent = hideScrollBarControl;
                }
                else
                {
                    this.VerticalScrollBar.Parent = this;
                }
            }
        }
        /// <summary>
        /// 引发 System.Windows.Forms.DataGridView.ColumnAdded 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.DataGridViewColumnEventArgs。</param>
        protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
        {
            if (this._root != null)
            {
                if (typeof(TreeGridColumn).IsAssignableFrom(e.Column.GetType()))
                {
                    if (_expandableColumn == null)
                    {
                        // identify the expanding column.			
                        _expandableColumn = (TreeGridColumn)e.Column;
                    }
                    else
                    {
                        // this.Columns.Remove(e.Column);
                        //throw new InvalidOperationException("Only one TreeGridColumn per TreeGridView is supported.");
                    }
                }

                // Expandable Grid doesn't support sorting. This is just a limitation of the sample.
                e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            base.OnColumnAdded(e);
        }
        #endregion
    }

    /// <summary>
    /// ColumnLayer
    /// </summary>
    public class ColumnLayer
    {
        /// <summary>
        /// 初始化类的新实例
        /// </summary>
        /// <param name="colIndex"></param>
        /// <param name="title"></param>
        /// <param name="level"></param>
        public ColumnLayer(int colIndex, string title, int level) :
            this(colIndex, title, level, 1, 0, 0)
        { }

        /// <summary>
        /// 初始化类的新实例
        /// </summary>
        /// <param name="colIndex"></param>
        /// <param name="title"></param>
        /// <param name="level"></param>
        /// <param name="rowSpan"></param>
        /// <param name="leftSpan"></param>
        /// <param name="rightSpan"></param>
        public ColumnLayer(int colIndex, string title, int level, int rowSpan, int leftSpan, int rightSpan)
        {
            this.ColumnIndex = colIndex;
            this.Title = title;
            this.Level = level;
            this.RowSpan = rowSpan;
            this.LeftSpan = leftSpan;
            this.RightSpan = rightSpan;
        }
        /// <summary>
        /// Title
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// ColumnIndex
        /// </summary>
        public int ColumnIndex { get; set; }
        /// <summary>
        /// Level
        /// </summary>
        public int Level { get; set; }
        /// <summary>
        /// RowSpan
        /// </summary>
        public int RowSpan { get; set; }
        /// <summary>
        /// LeftSpan
        /// </summary>
        public int LeftSpan { get; set; }
        /// <summary>
        /// RightSpan
        /// </summary>
        public int RightSpan { get; set; }
    }
}
